home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / toolmanager / source / prefs / dockwindow.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  39KB  |  1,297 lines

  1. /*
  2.  * dockwindow.c  V2.1
  3.  *
  4.  * dock edit window handling
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. struct DockNode {
  12.                  struct Node      dn_Node;
  13.                  ULONG            dn_Flags;
  14.                  char            *dn_HotKey;
  15.                  char            *dn_PubScreen;
  16.                  char            *dn_Title;
  17.                  struct TextAttr  dn_Font;
  18.                  char            *dn_FontDesc;
  19.                  LONG             dn_XPos;
  20.                  LONG             dn_YPos;
  21.                  ULONG            dn_Columns;
  22.                  struct List     *dn_ToolsList;
  23.                 };
  24.  
  25. /* Window data */
  26. static struct Gadget *gl;             /* Gadget list */
  27. static struct Window *w;              /* Window */
  28. static struct MsgPort *wp;            /* Window user port */
  29. static UWORD ww,wh;                   /* Window size */
  30. static struct DockNode *CurrentNode;
  31. static ULONG CurrentGadgetNum;
  32. static BOOL ReqOpen;
  33. static struct Requester DummyReq;
  34. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  35.                       CHECKBOXIDCMP|STRINGIDCMP|IDCMP_VANILLAKEY)
  36.  
  37. /* Gadget data */
  38. #define GAD_NAME_STR     0 /* Gadgets with labels (left side) */
  39. #define GAD_TITLE_STR    1
  40. #define GAD_HOTKEY_STR   2
  41. #define GAD_XPOS_INT     3
  42. #define GAD_YPOS_INT     4
  43. #define GAD_COLUMNS_INT  5
  44.  
  45. #define GAD_POSITION     6 /* Cycle gadget */
  46.  
  47. #define GAD_PSCREEN_BUT  7 /* Gadgets with labels (right side) */
  48. #define GAD_PSCREEN_TXT  8
  49. #define GAD_FONT_BUT     9
  50.  
  51. #define GAD_PSCREEN_STR 10
  52. #define GAD_FONT_TXT    11
  53.  
  54. #define GAD_TOOLS       12 /* Button gadget */
  55.  
  56. #define GAD_ACTIVATED   13 /* Checkbox gadgets */
  57. #define GAD_BACKDROP    14
  58. #define GAD_CENTERED    15
  59. #define GAD_FRONTMOST   16
  60. #define GAD_MENU        17
  61. #define GAD_PATTERN     18
  62. #define GAD_POPUP       19
  63. #define GAD_STICKY      20
  64. #define GAD_TEXT        21
  65. #define GAD_VERTICAL    22
  66.  
  67. #define GAD_OK          23 /* Button gadgets */
  68. #define GAD_CANCEL      24
  69. #define GADGETS         25
  70. static struct GadgetData gdata[GADGETS];
  71.  
  72. /* Gadget tags */
  73. static struct TagItem nametags[]={GTST_String,   NULL,
  74.                                   GTST_MaxChars, SGBUFLEN,
  75.                                   TAG_DONE};
  76.  
  77. static struct TagItem hotktags[]={GTST_String,   NULL,
  78.                                   GTST_MaxChars, SGBUFLEN,
  79.                                   TAG_DONE};
  80.  
  81. static struct TagItem pbsctags[]={GTST_String,   NULL,
  82.                                   GTST_MaxChars, SGBUFLEN,
  83.                                   TAG_DONE};
  84.  
  85. static struct TagItem fonttags[]={GTTX_Text,   NULL,
  86.                                   GTTX_Border, TRUE,
  87.                                   TAG_DONE};
  88.  
  89. static struct TagItem titletags[]={GTST_String,   NULL,
  90.                                    GTST_MaxChars, SGBUFLEN,
  91.                                    TAG_DONE};
  92.  
  93. static struct TagItem xpostags[]={GTIN_Number,   0,
  94.                                   GTIN_MaxChars, 10,
  95.                                   TAG_DONE};
  96.  
  97. static struct TagItem ypostags[]={GTIN_Number,   0,
  98.                                   GTIN_MaxChars, 10,
  99.                                   TAG_DONE};
  100.  
  101. static char *cyclelabels[3]={NULL, NULL, NULL};
  102. static struct TagItem cycletags[]={GTCY_Labels, (ULONG) cyclelabels,
  103.                                    GTCY_Active, 0,
  104.                                    TAG_DONE};
  105.  
  106. static struct TagItem colstags[]={GTIN_Number,   0,
  107.                                   GTIN_MaxChars, 10,
  108.                                   TAG_DONE};
  109.  
  110. static struct TagItem actitags[]={GTCB_Checked, FALSE,
  111.                                   GTCB_Scaled,  TRUE,
  112.                                   TAG_DONE};
  113.  
  114. static struct TagItem backdtags[]={GTCB_Checked, FALSE,
  115.                                    GTCB_Scaled,  TRUE,
  116.                                    TAG_DONE};
  117.  
  118. static struct TagItem centtags[]={GTCB_Checked, FALSE,
  119.                                   GTCB_Scaled,  TRUE,
  120.                                   TAG_DONE};
  121.  
  122. static struct TagItem fronttags[]={GTCB_Checked, FALSE,
  123.                                    GTCB_Scaled,  TRUE,
  124.                                    TAG_DONE};
  125.  
  126. static struct TagItem menutags[]={GTCB_Checked, FALSE,
  127.                                   GTCB_Scaled,  TRUE,
  128.                                   TAG_DONE};
  129.  
  130. static struct TagItem patttags[]={GTCB_Checked, FALSE,
  131.                                   GTCB_Scaled,  TRUE,
  132.                                   TAG_DONE};
  133.  
  134. static struct TagItem popuptags[]={GTCB_Checked, FALSE,
  135.                                    GTCB_Scaled,  TRUE,
  136.                                    TAG_DONE};
  137.  
  138. static struct TagItem stickytags[]={GTCB_Checked, FALSE,
  139.                                     GTCB_Scaled,  TRUE,
  140.                                     TAG_DONE};
  141.  
  142. static struct TagItem texttags[]={GTCB_Checked, FALSE,
  143.                                   GTCB_Scaled,  TRUE,
  144.                                   TAG_DONE};
  145.  
  146. static struct TagItem verttags[]={GTCB_Checked, FALSE,
  147.                                   GTCB_Scaled,  TRUE,
  148.                                   TAG_DONE};
  149.  
  150. /* Gadget vanilla key data */
  151. #define KEY_NAME     0
  152. #define KEY_TITLE    1
  153. #define KEY_HOTKEY   2
  154. #define KEY_XPOS     3
  155. #define KEY_YPOS     4
  156. #define KEY_COLS     5
  157. #define KEY_FONT     6
  158. #define KEY_PSCREEN  7
  159. #define KEY_EDIT     8
  160. #define KEY_ACTIVE   9
  161. #define KEY_BDROP   10
  162. #define KEY_CENTER  11
  163. #define KEY_FRONT   12
  164. #define KEY_MENU    13
  165. #define KEY_PATT    14
  166. #define KEY_POPUP   15
  167. #define KEY_STICKY  16
  168. #define KEY_TEXT    17
  169. #define KEY_VERT    18
  170. #define KEY_OK      19
  171. #define KEY_CANCEL  20
  172. static char KeyArray[KEY_CANCEL+1];
  173.  
  174. /* Init dock edit window */
  175. void InitDockEditWindow(UWORD left, UWORD fheight)
  176. {
  177.  ULONG llabwidth,lgadwidth,rlabwidth,rgadwidth;
  178.  ULONG cycwidth,cbwidth,butwidth,minstringwidth;
  179.  ULONG strheight=fheight+2;
  180.  ULONG i,tmp,yadd;
  181.  struct GadgetData *gd;
  182.  
  183.  /* Init strings */
  184.  gdata[GAD_NAME_STR].name    =AppStrings[MSG_WINDOW_NAME_GAD];
  185.  gdata[GAD_TITLE_STR].name   =AppStrings[MSG_DOCKWIN_TITLE_GAD];
  186.  gdata[GAD_HOTKEY_STR].name  =AppStrings[MSG_WINDOW_HOTKEY_GAD];
  187.  gdata[GAD_XPOS_INT].name    =AppStrings[MSG_WINDOW_LEFTEDGE_GAD];
  188.  gdata[GAD_YPOS_INT].name    =AppStrings[MSG_WINDOW_TOPEDGE_GAD];
  189.  gdata[GAD_COLUMNS_INT].name =AppStrings[MSG_DOCKWIN_COLUMNS_GAD];
  190.  cyclelabels[0]              =AppStrings[MSG_WINDOW_POSITION_OPEN_LABEL];
  191.  cyclelabels[1]              =AppStrings[MSG_WINDOW_POSITION_CLOSE_LABEL];
  192.  gdata[GAD_PSCREEN_TXT].name =AppStrings[MSG_WINDOW_PUBSCREEN_GAD];
  193.  gdata[GAD_FONT_BUT].name    =AppStrings[MSG_DOCKWIN_FONT_GAD];
  194.  gdata[GAD_TOOLS].name       =AppStrings[MSG_DOCKWIN_EDITTOOLS_GAD];
  195.  gdata[GAD_ACTIVATED].name   =AppStrings[MSG_DOCKWIN_ACTIVATED_GAD];
  196.  gdata[GAD_BACKDROP].name    =AppStrings[MSG_DOCKWIN_BACKDROP_GAD];
  197.  gdata[GAD_CENTERED].name    =AppStrings[MSG_DOCKWIN_CENTERED_GAD];
  198.  gdata[GAD_FRONTMOST].name   =AppStrings[MSG_DOCKWIN_FRONTMOST_GAD];
  199.  gdata[GAD_MENU].name        =AppStrings[MSG_DOCKWIN_MENU_GAD];
  200.  gdata[GAD_PATTERN].name     =AppStrings[MSG_DOCKWIN_PATTERN_GAD];
  201.  gdata[GAD_POPUP].name       =AppStrings[MSG_DOCKWIN_POPUP_GAD];
  202.  gdata[GAD_STICKY].name      =AppStrings[MSG_DOCKWIN_STICKY_GAD];
  203.  gdata[GAD_TEXT].name        =AppStrings[MSG_DOCKWIN_TEXT_GAD];
  204.  gdata[GAD_VERTICAL].name    =AppStrings[MSG_DOCKWIN_VERTICAL_GAD];
  205.  gdata[GAD_OK].name          =AppStrings[MSG_WINDOW_OK_GAD];
  206.  gdata[GAD_CANCEL].name      =AppStrings[MSG_WINDOW_CANCEL_GAD];
  207.  
  208.  /* Calculate maximum label width (left side) */
  209.  llabwidth=0;
  210.  gd=&gdata[GAD_NAME_STR];
  211.  for (i=GAD_NAME_STR; i<=GAD_COLUMNS_INT; i++, gd++)
  212.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > llabwidth)
  213.    llabwidth=tmp;
  214.  llabwidth+=INTERWIDTH;
  215.  
  216.  /* Calculate maximum gadget width (left side) */
  217.  minstringwidth=TextLength(&TmpRastPort,AppStrings[MSG_DOCKWIN_NEWNAME],
  218.                            strlen(AppStrings[MSG_DOCKWIN_NEWNAME]))
  219.                 +2*INTERWIDTH;
  220.  lgadwidth=minstringwidth;
  221.  
  222.  /* Calculate maximum cyclegadget width */
  223.  {
  224.   char **s;
  225.  
  226.   cycwidth=0;
  227.   s=cyclelabels;
  228.   for (i=0; i<=1; i++, s++)
  229.    if ((tmp=TextLength(&TmpRastPort,*s,strlen(*s))) > cycwidth)
  230.     cycwidth=tmp;
  231.   cycwidth+=5*INTERWIDTH;
  232.  }
  233.  if ((llabwidth+lgadwidth+INTERWIDTH) < cycwidth)
  234.   lgadwidth=cycwidth-llabwidth-INTERWIDTH;
  235.  
  236.  /* Calculate maximum label width (right side) */
  237.  gd=&gdata[GAD_PSCREEN_TXT];
  238.  rlabwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+INTERWIDTH;
  239.  gd++;
  240.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+2*INTERWIDTH)
  241.       > rlabwidth)
  242.   rlabwidth=tmp;
  243.  
  244.  /* Calculate maximum gadget width (right side) */
  245.  rgadwidth=minstringwidth+REQBUTTONWIDTH;
  246.  
  247.  /* Calculate maximum button gadget width */
  248.  gd=&gdata[GAD_TOOLS];
  249.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+2*INTERWIDTH;
  250.  if ((rlabwidth+rgadwidth+INTERWIDTH) < butwidth)
  251.   rgadwidth=butwidth-rlabwidth-INTERWIDTH;
  252.  
  253.  /* Calculate maximum checkbox gadget width */
  254.  cbwidth=0;
  255.  gd=&gdata[GAD_ACTIVATED];
  256.  for (i=GAD_ACTIVATED; i<=GAD_VERTICAL; i++, gd++)
  257.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > cbwidth)
  258.    cbwidth=tmp;
  259.  cbwidth+=CHECKBOX_WIDTH+INTERWIDTH;
  260.  if ((rlabwidth+rgadwidth) < 2*cbwidth)
  261.   rgadwidth=2*cbwidth-rlabwidth;
  262.  
  263.  /* Calculate minimum window width */
  264.  ww=llabwidth+lgadwidth+rlabwidth+rgadwidth+4*INTERWIDTH;
  265.  
  266.  /* Calculate button gadgets width */
  267.  gd=&gdata[GAD_OK];
  268.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  269.  gd++;
  270.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > butwidth)
  271.   butwidth=tmp;
  272.  butwidth+=2*INTERWIDTH;
  273.  if ((tmp=2*(butwidth+INTERWIDTH)) > ww) ww=tmp;
  274.  
  275.  /* Calculate minimum window height */
  276.  wh=9*fheight+10*INTERHEIGHT+16;
  277.  
  278.  /* Init gadgets */
  279.  gd=gdata;
  280.  tmp=(ww-llabwidth-lgadwidth-rlabwidth-rgadwidth-4*INTERWIDTH)/2;
  281.  lgadwidth+=tmp; /* String gadget length (left) */
  282.  rgadwidth+=tmp; /* String gadget length (right) */
  283.  llabwidth+=left+INTERWIDTH;
  284.  tmp=WindowTop+INTERHEIGHT;
  285.  yadd=strheight+INTERHEIGHT;
  286.  
  287.  /* Name string gadget */
  288.  gd->type=STRING_KIND;
  289.  gd->flags=PLACETEXT_LEFT;
  290.  gd->tags=nametags;
  291.  gd->left=llabwidth;
  292.  gd->top=tmp;
  293.  gd->width=lgadwidth;
  294.  gd->height=strheight;
  295.  tmp+=yadd;
  296.  
  297.  /* Title string gadget */
  298.  gd++;
  299.  gd->type=STRING_KIND;
  300.  gd->flags=PLACETEXT_LEFT;
  301.  gd->tags=titletags;
  302.  gd->left=llabwidth;
  303.  gd->top=tmp;
  304.  gd->width=lgadwidth;
  305.  gd->height=strheight;
  306.  tmp+=yadd;
  307.  
  308.  /* HotKey string gadget */
  309.  gd++;
  310.  gd->type=STRING_KIND;
  311.  gd->flags=PLACETEXT_LEFT;
  312.  gd->tags=hotktags;
  313.  gd->left=llabwidth;
  314.  gd->top=tmp;
  315.  gd->width=lgadwidth;
  316.  gd->height=strheight;
  317.  tmp+=2*yadd;
  318.  
  319.  /* LeftEdge integer gadget */
  320.  gd++;
  321.  gd->type=INTEGER_KIND;
  322.  gd->flags=PLACETEXT_LEFT;
  323.  gd->tags=xpostags;
  324.  gd->left=llabwidth;
  325.  gd->top=tmp;
  326.  gd->width=lgadwidth;
  327.  gd->height=strheight;
  328.  tmp+=yadd;
  329.  
  330.  /* TopEdge integer gadget */
  331.  gd++;
  332.  gd->type=INTEGER_KIND;
  333.  gd->flags=PLACETEXT_LEFT;
  334.  gd->tags=ypostags;
  335.  gd->left=llabwidth;
  336.  gd->top=tmp;
  337.  gd->width=lgadwidth;
  338.  gd->height=strheight;
  339.  tmp+=yadd;
  340.  
  341.  /* Columns integer gadget */
  342.  gd++;
  343.  gd->type=INTEGER_KIND;
  344.  gd->flags=PLACETEXT_LEFT;
  345.  gd->tags=colstags;
  346.  gd->left=llabwidth;
  347.  gd->top=tmp;
  348.  gd->width=lgadwidth;
  349.  gd->height=strheight;
  350.  
  351.  /* Position cycle gadget */
  352.  tmp=WindowTop+3*yadd+INTERHEIGHT;
  353.  gd++;
  354.  gd->type=CYCLE_KIND;
  355.  gd->flags=PLACETEXT_IN;
  356.  gd->tags=cycletags;
  357.  gd->left=left;
  358.  gd->top=tmp;
  359.  gd->width=lgadwidth+llabwidth-left;
  360.  gd->height=strheight;
  361.  
  362.  /* PubScreen button gadget */
  363.  tmp=WindowTop+INTERHEIGHT;
  364.  llabwidth=ww-rgadwidth-INTERWIDTH+left;
  365.  gd++;
  366.  gd->type=GENERIC_KIND;
  367.  gd->flags=0;
  368.  gd->left=llabwidth;
  369.  gd->top=tmp;
  370.  gd->width=REQBUTTONWIDTH;
  371.  gd->height=strheight;
  372.  
  373.  /* PubScreen txt gadget */
  374.  gd++;
  375.  gd->type=TEXT_KIND;
  376.  gd->flags=PLACETEXT_LEFT;
  377.  gd->left=llabwidth;
  378.  gd->top=tmp+strheight/2;
  379.  gd->width=0;
  380.  gd->height=0;
  381.  tmp+=yadd;
  382.  
  383.  /* Font button gadget */
  384.  gd++;
  385.  gd->type=BUTTON_KIND;
  386.  gd->flags=PLACETEXT_IN;
  387.  gd->left=llabwidth-rlabwidth-INTERWIDTH;
  388.  gd->top=tmp;
  389.  gd->width=rlabwidth;
  390.  gd->height=strheight;
  391.  
  392.  /* PubScreen string gadget */
  393.  tmp=WindowTop+INTERHEIGHT;
  394.  gd++;
  395.  gd->type=STRING_KIND;
  396.  gd->tags=pbsctags;
  397.  gd->left=llabwidth+REQBUTTONWIDTH;
  398.  gd->top=tmp;
  399.  gd->width=rgadwidth-REQBUTTONWIDTH;
  400.  gd->height=strheight;
  401.  tmp+=yadd;
  402.  
  403.  /* Font text gadget */
  404.  gd++;
  405.  gd->type=TEXT_KIND;
  406.  gd->tags=fonttags;
  407.  gd->left=llabwidth;
  408.  gd->top=tmp;
  409.  gd->width=rgadwidth;
  410.  gd->height=strheight;
  411.  tmp+=yadd;
  412.  
  413.  /* Tools button gadget */
  414.  llabwidth-=rlabwidth+INTERWIDTH;
  415.  gd++;
  416.  gd->type=BUTTON_KIND;
  417.  gd->flags=PLACETEXT_IN;
  418.  gd->left=llabwidth;
  419.  gd->top=tmp;
  420.  gd->width=ww-llabwidth-INTERWIDTH+left;
  421.  gd->height=strheight;
  422.  tmp+=yadd+1;
  423.  if (OSV39) tmp+=INTERHEIGHT/2;
  424.  
  425.  /* Activated checkbox gadget */
  426.  rlabwidth=(ww-llabwidth-INTERWIDTH+left-2*cbwidth)/3;
  427.  llabwidth+=rlabwidth;
  428.  cbwidth+=llabwidth+rlabwidth;
  429.  strheight=fheight-INTERHEIGHT;
  430.  
  431.  gd++;
  432.  gd->type=CHECKBOX_KIND;
  433.  gd->flags=PLACETEXT_RIGHT;
  434.  gd->tags=actitags;
  435.  gd->left=llabwidth;
  436.  gd->top=tmp;
  437.  gd->width=CHECKBOX_WIDTH;
  438.  gd->height=strheight;
  439.  
  440.  /* Backdrop checkbox gadget */
  441.  gd++;
  442.  gd->type=CHECKBOX_KIND;
  443.  gd->flags=PLACETEXT_RIGHT;
  444.  gd->tags=backdtags;
  445.  gd->left=cbwidth;
  446.  gd->top=tmp;
  447.  gd->width=CHECKBOX_WIDTH;
  448.  gd->height=strheight;
  449.  tmp+=yadd;
  450.  
  451.  /* Centered checkbox gadget */
  452.  gd++;
  453.  gd->type=CHECKBOX_KIND;
  454.  gd->flags=PLACETEXT_RIGHT;
  455.  gd->tags=centtags;
  456.  gd->left=llabwidth;
  457.  gd->top=tmp;
  458.  gd->width=CHECKBOX_WIDTH;
  459.  gd->height=strheight;
  460.  
  461.  /* Frontmost checkbox gadget */
  462.  gd++;
  463.  gd->type=CHECKBOX_KIND;
  464.  gd->flags=PLACETEXT_RIGHT;
  465.  gd->tags=fronttags;
  466.  gd->left=cbwidth;
  467.  gd->top=tmp;
  468.  gd->width=CHECKBOX_WIDTH;
  469.  gd->height=strheight;
  470.  tmp+=yadd;
  471.  
  472.  /* Menu checkbox gadget */
  473.  gd++;
  474.  gd->type=CHECKBOX_KIND;
  475.  gd->flags=PLACETEXT_RIGHT;
  476.  gd->tags=menutags;
  477.  gd->left=llabwidth;
  478.  gd->top=tmp;
  479.  gd->width=CHECKBOX_WIDTH;
  480.  gd->height=strheight;
  481.  
  482.  /* Pattern checkbox gadget */
  483.  gd++;
  484.  gd->type=CHECKBOX_KIND;
  485.  gd->flags=PLACETEXT_RIGHT;
  486.  gd->tags=patttags;
  487.  gd->left=cbwidth;
  488.  gd->top=tmp;
  489.  gd->width=CHECKBOX_WIDTH;
  490.  gd->height=strheight;
  491.  tmp+=yadd;
  492.  
  493.  /* PopUp checkbox gadget */
  494.  gd++;
  495.  gd->type=CHECKBOX_KIND;
  496.  gd->flags=PLACETEXT_RIGHT;
  497.  gd->tags=popuptags;
  498.  gd->left=llabwidth;
  499.  gd->top=tmp;
  500.  gd->width=CHECKBOX_WIDTH;
  501.  gd->height=strheight;
  502.  
  503.  /* Sticky checkbox gadget */
  504.  gd++;
  505.  gd->type=CHECKBOX_KIND;
  506.  gd->flags=PLACETEXT_RIGHT;
  507.  gd->tags=stickytags;
  508.  gd->left=cbwidth;
  509.  gd->top=tmp;
  510.  gd->width=CHECKBOX_WIDTH;
  511.  gd->height=strheight;
  512.  tmp+=yadd;
  513.  
  514.  /* Text checkbox gadget */
  515.  gd++;
  516.  gd->type=CHECKBOX_KIND;
  517.  gd->flags=PLACETEXT_RIGHT;
  518.  gd->tags=texttags;
  519.  gd->left=llabwidth;
  520.  gd->top=tmp;
  521.  gd->width=CHECKBOX_WIDTH;
  522.  gd->height=strheight;
  523.  
  524.  /* Vertical checkbox gadget */
  525.  gd++;
  526.  gd->type=CHECKBOX_KIND;
  527.  gd->flags=PLACETEXT_RIGHT;
  528.  gd->tags=verttags;
  529.  gd->left=cbwidth;
  530.  gd->top=tmp;
  531.  gd->width=CHECKBOX_WIDTH;
  532.  gd->height=strheight;
  533.  tmp+=yadd-1;
  534.  if (OSV39) tmp-=INTERHEIGHT/2;
  535.  
  536.  /* OK button gadget */
  537.  gd++;
  538.  gd->type=BUTTON_KIND;
  539.  gd->flags=PLACETEXT_IN;
  540.  gd->left=left;
  541.  gd->top=tmp;
  542.  gd->width=butwidth;
  543.  gd->height=fheight;
  544.  
  545.  /* Cancel button gadget */
  546.  gd++;
  547.  gd->type=BUTTON_KIND;
  548.  gd->flags=PLACETEXT_IN;
  549.  gd->left=ww-butwidth-INTERWIDTH+left;
  550.  gd->top=tmp;
  551.  gd->width=butwidth;
  552.  gd->height=fheight;
  553.  
  554.  /* Init vanilla key array */
  555.  KeyArray[KEY_NAME]   =FindVanillaKey(gdata[GAD_NAME_STR].name);
  556.  KeyArray[KEY_TITLE]  =FindVanillaKey(gdata[GAD_TITLE_STR].name);
  557.  KeyArray[KEY_HOTKEY] =FindVanillaKey(gdata[GAD_HOTKEY_STR].name);
  558.  KeyArray[KEY_XPOS]   =FindVanillaKey(gdata[GAD_XPOS_INT].name);
  559.  KeyArray[KEY_YPOS]   =FindVanillaKey(gdata[GAD_YPOS_INT].name);
  560.  KeyArray[KEY_COLS]   =FindVanillaKey(gdata[GAD_COLUMNS_INT].name);
  561.  KeyArray[KEY_FONT]   =FindVanillaKey(gdata[GAD_FONT_BUT].name);
  562.  KeyArray[KEY_PSCREEN]=FindVanillaKey(gdata[GAD_PSCREEN_TXT].name);
  563.  KeyArray[KEY_EDIT]   =FindVanillaKey(gdata[GAD_TOOLS].name);
  564.  KeyArray[KEY_ACTIVE] =FindVanillaKey(gdata[GAD_ACTIVATED].name);
  565.  KeyArray[KEY_BDROP]  =FindVanillaKey(gdata[GAD_BACKDROP].name);
  566.  KeyArray[KEY_CENTER] =FindVanillaKey(gdata[GAD_CENTERED].name);
  567.  KeyArray[KEY_FRONT]  =FindVanillaKey(gdata[GAD_FRONTMOST].name);
  568.  KeyArray[KEY_MENU]   =FindVanillaKey(gdata[GAD_MENU].name);
  569.  KeyArray[KEY_PATT]   =FindVanillaKey(gdata[GAD_PATTERN].name);
  570.  KeyArray[KEY_POPUP]  =FindVanillaKey(gdata[GAD_POPUP].name);
  571.  KeyArray[KEY_TEXT]   =FindVanillaKey(gdata[GAD_TEXT].name);
  572.  KeyArray[KEY_STICKY] =FindVanillaKey(gdata[GAD_STICKY].name);
  573.  KeyArray[KEY_VERT]   =FindVanillaKey(gdata[GAD_VERTICAL].name);
  574.  KeyArray[KEY_OK]     =FindVanillaKey(gdata[GAD_OK].name);
  575.  KeyArray[KEY_CANCEL] =FindVanillaKey(gdata[GAD_CANCEL].name);
  576.  
  577.  /* Init dummy requester structure */
  578.  InitRequester(&DummyReq);
  579. }
  580.  
  581. /* Free dock node */
  582. void FreeDockNode(struct Node *node)
  583. {
  584.  struct DockNode *dn=(struct DockNode *) node;
  585.  char *s;
  586.  
  587.  if (s=dn->dn_Node.ln_Name) free(s);
  588.  if (s=dn->dn_HotKey) free(s);
  589.  if (s=dn->dn_PubScreen) free(s);
  590.  if (s=dn->dn_Title) free(s);
  591.  if (s=dn->dn_Font.ta_Name) free(s);
  592.  if (s=dn->dn_FontDesc) free(s);
  593.  
  594.  /* Free tool list */
  595.  if (dn->dn_ToolsList) FreeToolsList(dn->dn_ToolsList);
  596.  
  597.  /* Free node */
  598.  FreeMem(dn,sizeof(struct DockNode));
  599. }
  600.  
  601. /* Build font descriptor string */
  602. static char *BuildFontDesc(struct TextAttr *ta)
  603. {
  604.  char *name;
  605.  
  606.  if (name=strdup(ta->ta_Name)) {
  607.   ULONG len=strlen(name);
  608.   UWORD size=ta->ta_YSize%10000; /* Safety hack... */
  609.   UWORD div=1000;
  610.   char *s=&name[len-5];
  611.   BOOL InNumber=FALSE;
  612.  
  613.   /* Overwrite ".font" */
  614.   *s++='/';
  615.   while (div) {
  616.    char c=size/div+'0';
  617.  
  618.    if ((c!='0') || InNumber) {
  619.     *s++=c;
  620.     InNumber=TRUE;
  621.    }
  622.    size%=div;
  623.    div/=10;
  624.   }
  625.   *s++='\0';
  626.  }
  627.  return(name);
  628. }
  629.  
  630. /* Copy dock node */
  631. struct Node *CopyDockNode(struct Node *node)
  632. {
  633.  struct DockNode *dn,*orignode=(struct DockNode *) node;
  634.  
  635.  /* Alloc memory for dock node */
  636.  if (dn=AllocMem(sizeof(struct DockNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  637.   /* Got an old node? */
  638.   if (orignode) {
  639.    /* Yes, copy it */
  640.    if ((!orignode->dn_Node.ln_Name || (dn->dn_Node.ln_Name=
  641.                                         strdup(orignode->dn_Node.ln_Name))) &&
  642.        (!orignode->dn_HotKey || (dn->dn_HotKey=strdup(orignode->dn_HotKey))) &&
  643.        (!orignode->dn_PubScreen || (dn->dn_PubScreen=
  644.                                      strdup(orignode->dn_PubScreen))) &&
  645.        (!orignode->dn_Title || (dn->dn_Title=strdup(orignode->dn_Title))) &&
  646.        (!orignode->dn_Font.ta_Name ||
  647.         ((dn->dn_Font.ta_Name=strdup(orignode->dn_Font.ta_Name)) &&
  648.          (dn->dn_FontDesc=BuildFontDesc(&orignode->dn_Font)))) &&
  649.        (!orignode->dn_ToolsList || (dn->dn_ToolsList=
  650.                                      CopyToolsList(orignode->dn_ToolsList)))) {
  651.     /* Copy flags & numbers */
  652.     dn->dn_XPos=orignode->dn_XPos;
  653.     dn->dn_YPos=orignode->dn_YPos;
  654.     dn->dn_Columns=orignode->dn_Columns;
  655.     dn->dn_Font.ta_YSize=orignode->dn_Font.ta_YSize;
  656.     dn->dn_Font.ta_Style=orignode->dn_Font.ta_Style;
  657.     dn->dn_Font.ta_Flags=orignode->dn_Font.ta_Flags;
  658.     dn->dn_Flags=orignode->dn_Flags;
  659.  
  660.     /* Return pointer to new node */
  661.     return(dn);
  662.    }
  663.   } else {
  664.    /* No, set defaults */
  665.    if (dn->dn_Node.ln_Name=strdup(AppStrings[MSG_DOCKWIN_NEWNAME])) {
  666.     dn->dn_Columns=1;
  667.     dn->dn_Flags=DOPOF_ACTIVATED;
  668.  
  669.     /* Return pointer to new node */
  670.     return(dn);
  671.    }
  672.   }
  673.  
  674.   FreeDockNode((struct Node *) dn);
  675.  }
  676.  /* Call failed */
  677.  return(NULL);
  678. }
  679.  
  680. /* Activate gadget and save pointer to it */
  681. static void MyActivateGadget(ULONG num)
  682. {
  683.  ActivateGadget(gdata[num].gadget,w,NULL);
  684. }
  685.  
  686. /* Open dock edit window */
  687. BOOL OpenDockEditWindow(struct Node *node, struct Window *parent)
  688. {
  689.  /* Copy node */
  690.  if (CurrentNode=(struct DockNode *) CopyDockNode(node)) {
  691.   /* Set tags */
  692.   nametags[0].ti_Data=(ULONG) CurrentNode->dn_Node.ln_Name;
  693.   titletags[0].ti_Data=(ULONG) CurrentNode->dn_Title;
  694.   hotktags[0].ti_Data=(ULONG) CurrentNode->dn_HotKey;
  695.   xpostags[0].ti_Data=CurrentNode->dn_XPos;
  696.   ypostags[0].ti_Data=CurrentNode->dn_YPos;
  697.   colstags[0].ti_Data=CurrentNode->dn_Columns;
  698.   pbsctags[0].ti_Data=(ULONG) CurrentNode->dn_PubScreen;
  699.   fonttags[0].ti_Data=(ULONG) CurrentNode->dn_FontDesc;
  700.   actitags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_ACTIVATED)!=0;
  701.   backdtags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_BACKDROP)!=0;
  702.   centtags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_CENTERED)!=0;
  703.   fronttags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_FRONTMOST)!=0;
  704.   menutags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_MENU)!=0;
  705.   patttags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_PATTERN)!=0;
  706.   popuptags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_POPUP)!=0;
  707.   stickytags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_STICKY)!=0;
  708.   texttags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_TEXT)!=0;
  709.   verttags[0].ti_Data=(CurrentNode->dn_Flags & DOPOF_VERTICAL)!=0;
  710.  
  711.   /* Create gadgets */
  712.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  713.    /* Open window */
  714.    if (w=OpenWindowTags(NULL,WA_Left,        parent->LeftEdge,
  715.                              WA_Top,         parent->TopEdge+WindowTop,
  716.                              WA_InnerWidth,  ww,
  717.                              WA_InnerHeight, wh,
  718.                              WA_AutoAdjust,  TRUE,
  719.                              WA_Title,       AppStrings[MSG_DOCKWIN_TITLE],
  720.                              WA_PubScreen,   PublicScreen,
  721.                              WA_Flags,       WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  722.                                              WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  723.                                              WFLG_ACTIVATE,
  724.                              TAG_DONE)) {
  725.     /* Init requester button gadgets */
  726.     InitReqButtonGadget(gdata[GAD_PSCREEN_BUT].gadget);
  727.  
  728.     /* Add gadgets to window */
  729.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  730.     RefreshGList(gl,w,NULL,(UWORD) -1);
  731.     GT_RefreshWindow(w,NULL);
  732.  
  733.     /* Activate name string gadget */
  734.     MyActivateGadget(GAD_NAME_STR);
  735.  
  736.     /* Set local variables */
  737.     w->UserPort=IDCMPPort;
  738.     w->UserData=(BYTE *) HandleDockEditWindowIDCMP;
  739.     ModifyIDCMP(w,WINDOW_IDCMP);
  740.     CurrentWindow=w;
  741.     ReqOpen=FALSE;
  742.  
  743.     /* All OK. */
  744.     return(TRUE);
  745.    }
  746.    FreeGadgets(gl);
  747.   }
  748.   FreeDockNode((struct Node *) CurrentNode);
  749.  }
  750.  /* Call failed */
  751.  return(FALSE);
  752. }
  753.  
  754. /* Close dock edit window */
  755. static void CloseDockEditWindow(void)
  756. {
  757.  /* Free resources */
  758.  if (MoveWindowPtr) CloseMoveWindow();
  759.  RemoveGList(w,gl,(UWORD) -1);
  760.  CloseWindowSafely(w);
  761.  FreeGadgets(gl);
  762. }
  763.  
  764. /* If move window open, move it to new position */
  765. static void MoveMoveWindow(void)
  766. {
  767.  /* Move window open? */
  768.  if (MoveWindowPtr) {
  769.   ULONG x,y;
  770.  
  771.   /* Read current position */
  772.   x=((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  773.   y=((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  774.  
  775.   /* Move move window */
  776.   MoveWindow(MoveWindowPtr,x-MoveWindowPtr->LeftEdge,y-MoveWindowPtr->TopEdge);
  777.  }
  778. }
  779.  
  780. /* Public screen gadget function */
  781. static void PubScreenGadgetFunc(void)
  782. {
  783.  if (!ReqOpen) {
  784.   /* Save current gadget number */
  785.   CurrentGadgetNum=GAD_PSCREEN_BUT;
  786.  
  787.   /* Open list requester */
  788.   if (OpenListRequester(LISTREQ_PUBSC,w)) {
  789.    /* Disable window */
  790.    DisableWindow(w,&DummyReq);
  791.  
  792.    /* Set update function */
  793.    UpdateWindow=UpdateDockEditWindow;
  794.    ReqOpen=TRUE;
  795.   }
  796.  }
  797. }
  798.  
  799. /* Font gadget function */
  800. static void FontGadgetFunc(void)
  801. {
  802.  struct TextAttr *newta;
  803.  
  804.  /* Set old font */
  805.  newta=(CurrentNode->dn_FontDesc) ? &CurrentNode->dn_Font : NULL;
  806.  
  807.  /* Open font requester */
  808.  if (newta=OpenFontRequester(w,&DummyReq,newta)) {
  809.   /* Font specified? */
  810.   if (newta->ta_Name) {
  811.    char *fontdesc;
  812.  
  813.    /* Build font descriptor */
  814.    if (fontdesc=BuildFontDesc(newta)) {
  815.     /* All OK. Set new font */
  816.     GT_SetGadgetAttrs(gdata[GAD_FONT_TXT].gadget,w,NULL,GTTX_Text,fontdesc,
  817.                                                         TAG_DONE);
  818.  
  819.     /* Throw away old font */
  820.     if (CurrentNode->dn_FontDesc) {
  821.      free(CurrentNode->dn_Font.ta_Name);
  822.      free(CurrentNode->dn_FontDesc);
  823.     }
  824.  
  825.     /* Set new font */
  826.     CurrentNode->dn_Font=*(newta);
  827.     CurrentNode->dn_FontDesc=fontdesc;
  828.    }
  829.   } else
  830.    /* User selected NO font, delete old one */
  831.    if (CurrentNode->dn_FontDesc) {
  832.     GT_SetGadgetAttrs(gdata[GAD_FONT_TXT].gadget,w,NULL,GTTX_Text,NULL,
  833.                                                         TAG_DONE);
  834.  
  835.     /* Free strings */
  836.     free(CurrentNode->dn_Font.ta_Name);
  837.     CurrentNode->dn_Font.ta_Name=NULL;
  838.     free(CurrentNode->dn_FontDesc);
  839.     CurrentNode->dn_FontDesc=NULL;
  840.    }
  841.  }
  842. }
  843.  
  844. /* Edit gadget function */
  845. static void EditGadgetFunc(void)
  846. {
  847.  if (!ReqOpen) {
  848.   /* Save current gadget number */
  849.   CurrentGadgetNum=GAD_TOOLS;
  850.  
  851.   /* Open edit window */
  852.   if (OpenDockListEditWindow(CurrentNode->dn_ToolsList,w)) {
  853.    /* Disable window */
  854.    DisableWindow(w,&DummyReq);
  855.  
  856.    /* Set update function */
  857.    UpdateWindow=UpdateDockEditWindow;
  858.    ReqOpen=TRUE;
  859.   } else
  860.    DisplayBeep(NULL);
  861.  }
  862. }
  863.  
  864. /* OK gadget function */
  865. static struct Node *OKGadgetFunc(void)
  866. {
  867.  struct Node *rc;
  868.  char *s;
  869.  
  870.  /* Free old string */
  871.  if (s=CurrentNode->dn_Node.ln_Name) free(s);
  872.  CurrentNode->dn_Node.ln_Name=NULL;
  873.  if (s=CurrentNode->dn_HotKey) free(s);
  874.  CurrentNode->dn_HotKey=NULL;
  875.  if (s=CurrentNode->dn_PubScreen) free(s);
  876.  CurrentNode->dn_PubScreen=NULL;
  877.  if (s=CurrentNode->dn_Title) free(s);
  878.  CurrentNode->dn_Title=NULL;
  879.  
  880.  /* Duplicate new string */
  881.  if (((CurrentNode->dn_Node.ln_Name=
  882.         DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) &&
  883.      ((CurrentNode->dn_HotKey=
  884.         DuplicateBuffer(gdata[GAD_HOTKEY_STR].gadget)) != (char *) -1) &&
  885.      ((CurrentNode->dn_PubScreen=
  886.         DuplicateBuffer(gdata[GAD_PSCREEN_STR].gadget)) != (char *) -1) &&
  887.      ((CurrentNode->dn_Title=
  888.         DuplicateBuffer(gdata[GAD_TITLE_STR].gadget)) != (char *) -1)) {
  889.   /* Copy integer gadget values */
  890.   CurrentNode->dn_XPos=
  891.    ((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  892.   CurrentNode->dn_YPos=
  893.    ((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  894.   CurrentNode->dn_Columns=
  895.    ((struct StringInfo *) gdata[GAD_COLUMNS_INT].gadget->SpecialInfo)->LongInt;
  896.  
  897.   rc=(struct Node *) CurrentNode;
  898.  } else {
  899.   /* Couldn't copy strings */
  900.   rc=(struct Node *) -1;
  901.   FreeDockNode((struct Node *) CurrentNode);
  902.  }
  903.  return(rc);
  904. }
  905.  
  906. /* Handle dock edit window IDCMP events */
  907. void *HandleDockEditWindowIDCMP(struct IntuiMessage *msg)
  908. {
  909.  struct Node *NewNode=NULL;
  910.  
  911.  /* Which IDCMP class? */
  912.  switch (msg->Class) {
  913.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  914.                             FreeDockNode((struct Node *) CurrentNode);
  915.                             break;
  916.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  917.                             GT_EndRefresh(w,TRUE);
  918.                             break;
  919.   case IDCMP_GADGETUP:
  920.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  921.     case GAD_XPOS_INT:    MoveMoveWindow();
  922.                           break;
  923.     case GAD_YPOS_INT:    MoveMoveWindow();
  924.                           break;
  925.     case GAD_POSITION:    /* Move window open? */
  926.                           if (MoveWindowPtr)
  927.                            /* Yes, close move window */
  928.                            CloseMoveWindow();
  929.                           else {
  930.                            /* No. Open it! */
  931.                            MoveWindowOffX=0;
  932.                            MoveWindowOffY=0;
  933.  
  934.                            /* Open move window */
  935.                            OpenMoveWindow(w,gdata[GAD_XPOS_INT].gadget,
  936.                                             gdata[GAD_YPOS_INT].gadget);
  937.                           }
  938.                           break;
  939.     case GAD_PSCREEN_BUT: PubScreenGadgetFunc();
  940.                           break;
  941.     case GAD_FONT_BUT:    FontGadgetFunc();
  942.                           break;
  943.     case GAD_ACTIVATED:   /* Toggle flag */
  944.                           CurrentNode->dn_Flags^=DOPOF_ACTIVATED;
  945.                           break;
  946.     case GAD_BACKDROP:    /* Toggle flag */
  947.                           CurrentNode->dn_Flags^=DOPOF_BACKDROP;
  948.                           break;
  949.     case GAD_CENTERED:    /* Toggle flag */
  950.                           CurrentNode->dn_Flags^=DOPOF_CENTERED;
  951.                           break;
  952.     case GAD_FRONTMOST:   /* Toggle flag */
  953.                           CurrentNode->dn_Flags^=DOPOF_FRONTMOST;
  954.                           break;
  955.     case GAD_MENU:        /* Toggle flag */
  956.                           CurrentNode->dn_Flags^=DOPOF_MENU;
  957.                           break;
  958.     case GAD_PATTERN:     /* Toggle flag */
  959.                           CurrentNode->dn_Flags^=DOPOF_PATTERN;
  960.                           break;
  961.     case GAD_POPUP:       /* Toggle flag */
  962.                           CurrentNode->dn_Flags^=DOPOF_POPUP;
  963.                           break;
  964.     case GAD_STICKY:      /* Toggle flag */
  965.                           CurrentNode->dn_Flags^=DOPOF_STICKY;
  966.                           break;
  967.     case GAD_TEXT:        /* Toggle flag */
  968.                           CurrentNode->dn_Flags^=DOPOF_TEXT;
  969.                           break;
  970.     case GAD_VERTICAL:    /* Toggle flag */
  971.                           CurrentNode->dn_Flags^=DOPOF_VERTICAL;
  972.                           break;
  973.     case GAD_TOOLS:       EditGadgetFunc();
  974.                           break;
  975.     case GAD_OK:          NewNode=OKGadgetFunc();
  976.                           break;
  977.     case GAD_CANCEL:      NewNode=(struct Node *) -1;
  978.                           FreeDockNode((struct Node *) CurrentNode);
  979.                           break;
  980.    }
  981.    break;
  982.   case IDCMP_VANILLAKEY:
  983.    switch (MatchVanillaKey(msg->Code,KeyArray)) {
  984.     case KEY_NAME:    MyActivateGadget(GAD_NAME_STR);
  985.                       break;
  986.     case KEY_TITLE:   MyActivateGadget(GAD_TITLE_STR);
  987.                       break;
  988.     case KEY_HOTKEY:  MyActivateGadget(GAD_HOTKEY_STR);
  989.                       break;
  990.     case KEY_XPOS:    MyActivateGadget(GAD_XPOS_INT);
  991.                       break;
  992.     case KEY_YPOS:    MyActivateGadget(GAD_YPOS_INT);
  993.                       break;
  994.     case KEY_COLS:    MyActivateGadget(GAD_COLUMNS_INT);
  995.                       break;
  996.     case KEY_PSCREEN: PubScreenGadgetFunc();
  997.                       break;
  998.     case KEY_FONT:    FontGadgetFunc();
  999.                       break;
  1000.     case KEY_EDIT:    EditGadgetFunc();
  1001.                       break;
  1002.     case KEY_ACTIVE:  /* Toggle flag */
  1003.                       CurrentNode->dn_Flags^=DOPOF_ACTIVATED;
  1004.  
  1005.                       /* Set check box gadget */
  1006.                       GT_SetGadgetAttrs(gdata[GAD_ACTIVATED].gadget,w,NULL,
  1007.                        GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_ACTIVATED),
  1008.                        TAG_DONE);
  1009.  
  1010.                       break;
  1011.     case KEY_BDROP:  /* Toggle flag */
  1012.                      CurrentNode->dn_Flags^=DOPOF_BACKDROP;
  1013.  
  1014.                      /* Set check box gadget */
  1015.                      GT_SetGadgetAttrs(gdata[GAD_BACKDROP].gadget,w,NULL,
  1016.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_BACKDROP),
  1017.                       TAG_DONE);
  1018.  
  1019.                      break;
  1020.     case KEY_CENTER: /* Toggle flag */
  1021.                      CurrentNode->dn_Flags^=DOPOF_CENTERED;
  1022.  
  1023.                      /* Set check box gadget */
  1024.                      GT_SetGadgetAttrs(gdata[GAD_CENTERED].gadget,w,NULL,
  1025.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_CENTERED),
  1026.                       TAG_DONE);
  1027.  
  1028.                      break;
  1029.     case KEY_FRONT:  /* Toggle flag */
  1030.                      CurrentNode->dn_Flags^=DOPOF_FRONTMOST;
  1031.  
  1032.                      /* Set check box gadget */
  1033.                      GT_SetGadgetAttrs(gdata[GAD_FRONTMOST].gadget,w,NULL,
  1034.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_FRONTMOST),
  1035.                       TAG_DONE);
  1036.  
  1037.                      break;
  1038.     case KEY_MENU:   /* Toggle flag */
  1039.                      CurrentNode->dn_Flags^=DOPOF_MENU;
  1040.  
  1041.                      /* Set check box gadget */
  1042.                      GT_SetGadgetAttrs(gdata[GAD_MENU].gadget,w,NULL,
  1043.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_MENU),
  1044.                       TAG_DONE);
  1045.  
  1046.                      break;
  1047.     case KEY_PATT:   /* Toggle flag */
  1048.                      CurrentNode->dn_Flags^=DOPOF_PATTERN;
  1049.  
  1050.                      /* Set check box gadget */
  1051.                      GT_SetGadgetAttrs(gdata[GAD_PATTERN].gadget,w,NULL,
  1052.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_PATTERN),
  1053.                       TAG_DONE);
  1054.  
  1055.                      break;
  1056.     case KEY_POPUP:  /* Toggle flag */
  1057.                      CurrentNode->dn_Flags^=DOPOF_POPUP;
  1058.  
  1059.                      /* Set check box gadget */
  1060.                      GT_SetGadgetAttrs(gdata[GAD_POPUP].gadget,w,NULL,
  1061.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_POPUP),
  1062.                       TAG_DONE);
  1063.  
  1064.                      break;
  1065.     case KEY_STICKY: /* Toggle flag */
  1066.                      CurrentNode->dn_Flags^=DOPOF_STICKY;
  1067.  
  1068.                      /* Set check box gadget */
  1069.                      GT_SetGadgetAttrs(gdata[GAD_STICKY].gadget,w,NULL,
  1070.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_STICKY),
  1071.                       TAG_DONE);
  1072.  
  1073.                      break;
  1074.     case KEY_TEXT:   /* Toggle flag */
  1075.                      CurrentNode->dn_Flags^=DOPOF_TEXT;
  1076.  
  1077.                      /* Set check box gadget */
  1078.                      GT_SetGadgetAttrs(gdata[GAD_TEXT].gadget,w,NULL,
  1079.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_TEXT),
  1080.                       TAG_DONE);
  1081.  
  1082.                      break;
  1083.     case KEY_VERT:   /* Toggle flag */
  1084.                      CurrentNode->dn_Flags^=DOPOF_VERTICAL;
  1085.  
  1086.                      /* Set check box gadget */
  1087.                      GT_SetGadgetAttrs(gdata[GAD_VERTICAL].gadget,w,NULL,
  1088.                       GTCB_Checked, (CurrentNode->dn_Flags & DOPOF_VERTICAL),
  1089.                       TAG_DONE);
  1090.  
  1091.                      break;
  1092.     case KEY_OK:     NewNode=OKGadgetFunc();
  1093.                      break;
  1094.     case KEY_CANCEL: NewNode=(struct Node *) -1;
  1095.                      FreeDockNode((struct Node *) CurrentNode);
  1096.                      break;
  1097.    }
  1098.    break;
  1099.  }
  1100.  
  1101.  /* Close window? */
  1102.  if (NewNode) {
  1103.   /* Yes. But first reply message!!! */
  1104.   GT_ReplyIMsg(msg);
  1105.   CloseDockEditWindow();
  1106.  }
  1107.  
  1108.  return(NewNode);
  1109. }
  1110.  
  1111. /* Update dock edit window */
  1112. void UpdateDockEditWindow(void *data)
  1113. {
  1114.  /* Which data? */
  1115.  switch (CurrentGadgetNum) {
  1116.   case GAD_PSCREEN_BUT: /* Got data? */
  1117.                         if (data != LREQRET_CANCEL) {
  1118.                          char *new;
  1119.  
  1120.                          /* Selected something? */
  1121.                          new=(data == LREQRET_NOSELECT) ?
  1122.                               NULL : ((struct Node *) data)->ln_Name;
  1123.  
  1124.                          /* set new public screen name */
  1125.                          GT_SetGadgetAttrs(gdata[GAD_PSCREEN_STR].gadget,w,
  1126.                                            NULL,GTST_String,new,TAG_DONE);
  1127.                         }
  1128.                         break;
  1129.   case GAD_TOOLS:       /* Got data? */
  1130.                         if (data != (void *) -1) {
  1131.                          /* Free old tools list */
  1132.                          if (CurrentNode->dn_ToolsList)
  1133.                           FreeToolsList(CurrentNode->dn_ToolsList);
  1134.  
  1135.                          /* Set new tools list */
  1136.                          CurrentNode->dn_ToolsList=data;
  1137.                         }
  1138.                         break;
  1139.  }
  1140.  
  1141.  /* Enable window */
  1142.  EnableWindow(w,&DummyReq,WINDOW_IDCMP);
  1143.  
  1144.  /* Restore update function pointer */
  1145.  UpdateWindow=UpdateMainWindow;
  1146.  CurrentWindow=w;
  1147.  ReqOpen=FALSE;
  1148. }
  1149.  
  1150. /* Read TMDO IFF chunk into Dock node */
  1151. struct Node *ReadDockNode(UBYTE *buf)
  1152. {
  1153.  struct DockNode *dn;
  1154.  
  1155.  /* Allocate memory for node */
  1156.  if (dn=AllocMem(sizeof(struct DockNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  1157.   struct DockPrefsObject *dpo=(struct DockPrefsObject *) buf;
  1158.   ULONG sbits=dpo->dpo_StringBits;
  1159.   UBYTE *ptr=(UBYTE *) &dpo[1];
  1160.   struct List *toolslist;
  1161.  
  1162.   if ((!(sbits & DOPO_NAME) || (dn->dn_Node.ln_Name=GetConfigStr(&ptr))) &&
  1163.       (!(sbits & DOPO_HOTKEY) || (dn->dn_HotKey=GetConfigStr(&ptr))) &&
  1164.       (!(sbits & DOPO_PSCREEN) || (dn->dn_PubScreen=GetConfigStr(&ptr))) &&
  1165.       (!(sbits & DOPO_TITLE) || (dn->dn_Title=GetConfigStr(&ptr))) &&
  1166.       (!(sbits & DOPO_FONTNAME) || (dn->dn_Font.ta_Name=GetConfigStr(&ptr))) &&
  1167.       (toolslist=malloc(sizeof(struct List)))) {
  1168.    LONG tools=0;
  1169.    UBYTE tlflags;
  1170.  
  1171.    /* Init list */
  1172.    NewList(toolslist);
  1173.    dn->dn_ToolsList=toolslist;
  1174.  
  1175.    /* Get tools */
  1176.    while ((tlflags=*ptr++) & DOPOT_CONTINUE) {
  1177.     struct ToolNode *tn;
  1178.  
  1179.     if (tn=AllocMem(sizeof(struct ToolNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  1180.      /* Add tool to list */
  1181.      AddTail(toolslist,(struct Node *) tn);
  1182.  
  1183.      if ((!(tlflags & DOPOT_EXEC) || (tn->tn_Node.ln_Name=
  1184.                                        GetConfigStr(&ptr))) &&
  1185.          (!(tlflags & DOPOT_IMAGE) || (tn->tn_Image=GetConfigStr(&ptr))) &&
  1186.          (!(tlflags & DOPOT_SOUND) || (tn->tn_Sound=GetConfigStr(&ptr))))
  1187.       /* All OK. */
  1188.       tools++;
  1189.      else {
  1190.       /* Error */
  1191.       tools=-1;
  1192.       break;
  1193.      }
  1194.     } else {
  1195.      /* No memory. */
  1196.      tools=-1;
  1197.      break;
  1198.     }
  1199.    }
  1200.  
  1201.    /* Error? */
  1202.    if (tools!=-1) {
  1203.     /* Got tools? */
  1204.     if (tools==0) {
  1205.      /* No, free list structure */
  1206.      free(toolslist);
  1207.      dn->dn_ToolsList=NULL;
  1208.     }
  1209.  
  1210.     /* Copy flags & values */
  1211.     dn->dn_Flags=dpo->dpo_Flags;
  1212.     dn->dn_XPos=dpo->dpo_XPos;
  1213.     dn->dn_YPos=dpo->dpo_YPos;
  1214.     dn->dn_Columns=dpo->dpo_Columns;
  1215.     dn->dn_Font.ta_YSize=dpo->dpo_Font.ta_YSize;
  1216.     dn->dn_Font.ta_Style=dpo->dpo_Font.ta_Style;
  1217.     dn->dn_Font.ta_Flags=dpo->dpo_Font.ta_Flags;
  1218.  
  1219.     /* All OK. */
  1220.     return(dn);
  1221.    }
  1222.   }
  1223.  
  1224.   /* Call failed */
  1225.   FreeDockNode((struct Node *) dn);
  1226.  }
  1227.  return(NULL);
  1228. }
  1229.  
  1230. /* Write Dock node to TMDO IFF chunk */
  1231. BOOL WriteDockNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  1232. {
  1233.  struct DockNode *dn=(struct DockNode *) node;
  1234.  struct DockPrefsObject *dpo=(struct DockPrefsObject *) buf;
  1235.  ULONG sbits=0;
  1236.  UBYTE *ptr=(UBYTE *) &dpo[1];
  1237.  
  1238.  /* Copy strings */
  1239.  if (PutConfigStr(dn->dn_Node.ln_Name,&ptr)) sbits|=DOPO_NAME;
  1240.  if (PutConfigStr(dn->dn_HotKey,&ptr)) sbits|=DOPO_HOTKEY;
  1241.  if (PutConfigStr(dn->dn_PubScreen,&ptr)) sbits|=DOPO_PSCREEN;
  1242.  if (PutConfigStr(dn->dn_Title,&ptr)) sbits|=DOPO_TITLE;
  1243.  if (PutConfigStr(dn->dn_Font.ta_Name,&ptr)) sbits|=DOPO_FONTNAME;
  1244.  
  1245.  /* set string bits */
  1246.  dpo->dpo_StringBits=sbits;
  1247.  
  1248.  /* Write tool list */
  1249.  if (dn->dn_ToolsList) {
  1250.   struct ToolNode *tn=GetHead(dn->dn_ToolsList);
  1251.  
  1252.   while (tn) {
  1253.    UBYTE *flptr=ptr++;
  1254.    UBYTE tfl=DOPOT_CONTINUE;
  1255.  
  1256.    if (PutConfigStr(tn->tn_Node.ln_Name,&ptr)) tfl|=DOPOT_EXEC;
  1257.    if (PutConfigStr(tn->tn_Image,&ptr)) tfl|=DOPOT_IMAGE;
  1258.    if (PutConfigStr(tn->tn_Sound,&ptr)) tfl|=DOPOT_SOUND;
  1259.  
  1260.    /* Put flags */
  1261.    *flptr=tfl;
  1262.  
  1263.    /* Get next node */
  1264.    tn=GetSucc(tn);
  1265.   }
  1266.  }
  1267.  
  1268.  /* Append terminator */
  1269.  *ptr++=0;
  1270.  
  1271.  /* Copy flags & values */
  1272.  dpo->dpo_Flags=dn->dn_Flags;
  1273.  dpo->dpo_XPos=dn->dn_XPos;
  1274.  dpo->dpo_YPos=dn->dn_YPos;
  1275.  dpo->dpo_Columns=dn->dn_Columns;
  1276.  dpo->dpo_Font.ta_YSize=dn->dn_Font.ta_YSize;
  1277.  dpo->dpo_Font.ta_Style=dn->dn_Font.ta_Style;
  1278.  dpo->dpo_Font.ta_Flags=dn->dn_Font.ta_Flags;
  1279.  
  1280.  /* calculate length */
  1281.  sbits=ptr-buf;
  1282.  
  1283.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  1284.  
  1285.  /* Open chunk */
  1286.  if (PushChunk(iff,0,ID_TMDO,sbits)) return(FALSE);
  1287.  
  1288.  /* Write chunk */
  1289.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  1290.  
  1291.  /* Close chunk */
  1292.  if (PopChunk(iff)) return(FALSE);
  1293.  
  1294.  /* All OK. */
  1295.  return(TRUE);
  1296. }
  1297.